package com.fx.zmlzml.service.impl;

import com.fx.zmlzml.algorithm.ga.GaConfig;
import com.fx.zmlzml.algorithm.ga.Individual;
import com.fx.zmlzml.domain.dto.AhpPcComponentPriceWeightDTO;
import com.fx.zmlzml.domain.dto.BudgetPriceDTO;
import com.fx.zmlzml.domain.dto.PcComponentDTO;
import com.fx.zmlzml.domain.dto.PcDTO;
import com.fx.zmlzml.domain.vo.PcVO;
import com.fx.zmlzml.entity.*;
import com.fx.zmlzml.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * PC配置服务实现类
 * 该类提供基于遗传算法的电脑配置推荐功能，根据用户预算推荐最优的硬件组合
 */
@Service
public class PcServiceImpl implements PcService {

    @Autowired
    private PcComponentBudgetPriceRangeService pcComponentBudgetPriceRangeService; // 硬件组件预算价格范围服务，用于计算硬件组件的预算价格范围

    @Autowired
    private PcMotherboardService pcMotherboardService; // 主板服务，用于获取主板相关数据

    @Autowired
    private PcCpuService pcCpuService; // CPU服务，用于获取CPU相关数据

    @Autowired
    private PcCoolerService pcCoolerService; // 散热器服务，用于获取散热器相关数据

    @Autowired
    private PcGpuService pcGpuService; // 显卡服务，用于获取显卡相关数据

    @Autowired
    private PcMemoryService pcMemoryService; // 内存服务，用于获取内存相关数据

    @Autowired
    private PcHardDiskService pcHardDiskService; // 硬盘服务，用于获取硬盘相关数据

    @Autowired
    private PcPowerSupplyService pcPowerSupplyService; // 电源服务，用于获取电源相关数据

    @Autowired
    private PcCaseService pcCaseService; // 机箱服务，用于获取机箱相关数据

    @Override
    public PcComponentDTO getPcComponentByWeight(AhpPcComponentPriceWeightDTO dto) {
        PcComponentDTO pcComponentDTO = new PcComponentDTO();

        // 从DTO中提取所有硬件组件的价格
        BudgetPriceDTO budgetPriceDTO = pcComponentBudgetPriceRangeService.getBudgetPriceRange(dto);

        // 获取所有硬件组件数据
        List<PcMotherboard> motherboards = pcMotherboardService.getListByParams(budgetPriceDTO.getMaxMotherboardPrice(), budgetPriceDTO.getMinMotherboardPrice());
        List<PcCpu> cpus = pcCpuService.getListByParams(budgetPriceDTO.getMaxCpuPrice(), budgetPriceDTO.getMinCpuPrice());
        List<PcCooler> coolers = pcCoolerService.getListByParams(budgetPriceDTO.getMaxCoolerPrice(), budgetPriceDTO.getMinCoolerPrice());
        List<PcGpu> gpus = pcGpuService.getListByParams(budgetPriceDTO.getMaxGpuPrice(), budgetPriceDTO.getMinGpuPrice());
        List<PcMemory> memories = pcMemoryService.getListByParams(budgetPriceDTO.getMaxMemoryPrice(), budgetPriceDTO.getMinMemoryPrice());
        List<PcHardDisk> hardDisks = pcHardDiskService.getListByParams(budgetPriceDTO.getMaxHardDiskPrice(), budgetPriceDTO.getMinHardDiskPrice());
        List<PcPowerSupply> powerSupplies = pcPowerSupplyService.getListByParams(budgetPriceDTO.getMaxPowerSupplyPrice(), budgetPriceDTO.getMinPowerSupplyPrice());
        List<PcCase> cases = pcCaseService.getListByParams(budgetPriceDTO.getMaxCasePrice(), budgetPriceDTO.getMinCasePrice());

        pcComponentDTO.setPcMotherboards(motherboards);
        pcComponentDTO.setPcCpus(cpus);
        pcComponentDTO.setPcCoolers(coolers);
        pcComponentDTO.setPcGpus(gpus);
        pcComponentDTO.setPcMemorys(memories);
        pcComponentDTO.setPcHardDisks(hardDisks);
        pcComponentDTO.setPcPowerSupplies(powerSupplies);
        pcComponentDTO.setPcCases(cases);

        return pcComponentDTO;
    }

    /**
     * 根据目标价格使用遗传算法推荐最佳电脑配置组合
     * 该方法使用遗传算法来寻找在给定预算下性能最优的电脑硬件配置
     * 算法通过多代进化，逐步优化配置组合，最终返回适应度最高的配置
     * 该方法通过遗传算法的多代进化过程，优化配置组合，最终返回符合预算的最佳配置
     *
     * @param ahpPcComponentPriceWeightDTO 包含目标价格和组件价格权重的DTO，用于指定推荐预算和组件重要性
     * @return 符合预算的最佳电脑配置列表，按照适应度从高到低排序
     */
    @Override
    public List<PcVO> getAiPcListByPrice(AhpPcComponentPriceWeightDTO ahpPcComponentPriceWeightDTO) {
        // 调用入参校验方法，确保输入参数符合要求
        validateInputParameters(ahpPcComponentPriceWeightDTO);
        PcComponentDTO pcComponentDTO = getPcComponentByWeight(ahpPcComponentPriceWeightDTO);
        // 初始化种群
        List<PcDTO> populations = initializePopulation(pcComponentDTO, GaConfig.Easy.POPULATION_SIZE, ahpPcComponentPriceWeightDTO);

        // 主遗传算法循环
        for (int i = 0; i < GaConfig.Easy.MAX_GENERATIONS; i++) {
            // 1. 评估当前种群中每个个体的适应度，适应度基于价格匹配度、组件完整性和兼容性计算
            List<Individual> evaluatedPopulation = evaluatePopulation(populations, ahpPcComponentPriceWeightDTO.getBudgetPrice());
            // 2. 按照适应度从高到低对种群进行排序，确保优秀个体排在前面
            evaluatedPopulation.sort((a, b) -> Double.compare(b.fitness(), a.fitness()));
            // 计算当前种群的多样性
            double diversity = calculatePopulationDiversity(evaluatedPopulation);
            // 根据种群多样性动态调整变异率
            double currentMutationRate = GaConfig.Easy.BASE_MUTATION_RATE;
            if (diversity < GaConfig.Easy.DIVERSITY_THRESHOLD) {
                // 多样性不足时增加变异率，以促进种群多样性
                currentMutationRate = Math.min(0.3, GaConfig.Easy.BASE_MUTATION_RATE * (1 + (GaConfig.Easy.DIVERSITY_THRESHOLD - diversity) / GaConfig.Easy.DIVERSITY_THRESHOLD));
            }
            // 创建新一代种群
            List<PcDTO> newPopulation = new ArrayList<>();
            // 保留精英个体
            for (int perfect = 0; perfect < GaConfig.Easy.ELITISM_COUNT && perfect < evaluatedPopulation.size(); perfect++) {
                newPopulation.add(evaluatedPopulation.get(i).pc());
            }
            // 通过选择、交叉和变异生成新个体
            Random random = new Random();
            while (newPopulation.size() < GaConfig.Easy.POPULATION_SIZE) {
                // 选择父代 - 结合轮盘赌和锦标赛选择
                Individual parent1 = selectParentTournament(evaluatedPopulation, 3); // 3个个体的锦标赛
                Individual parent2 = selectParentTournament(evaluatedPopulation, 3);

                // 交叉操作
                List<PcDTO> children = new ArrayList<>();
                if (random.nextDouble() < GaConfig.Easy.BASE_CROSSOVER_RATE) {
                    children = crossover(parent1.pc(), parent2.pc());
                } else {
                    // 不进行交叉，直接复制父代
                    children.add(new PcDTO());
                    children.get(0).setPcMotherboard(parent1.pc().getPcMotherboard());
                    children.get(0).setPcCpu(parent1.pc().getPcCpu());
                    children.get(0).setPcCooler(parent1.pc().getPcCooler());
                    children.get(0).setPcGpu(parent1.pc().getPcGpu());
                    children.get(0).setPcMemory(parent1.pc().getPcMemory());
                    children.get(0).setPcHardDisk(parent1.pc().getPcHardDisk());
                    children.get(0).setPcPowerSupply(parent1.pc().getPcPowerSupply());
                    children.get(0).setPcCase(parent1.pc().getPcCase());
                }

                // 变异操作
                for (PcDTO child : children) {
                    if (random.nextDouble() < currentMutationRate) {
                        // 智能变异：优先变异适应度较低的组件
                        smartMutate(child,  pcComponentDTO.getPcMotherboards(),
                                            pcComponentDTO.getPcCpus(),
                                            pcComponentDTO.getPcCoolers(),
                                            pcComponentDTO.getPcGpus(),
                                            pcComponentDTO.getPcMemorys(),
                                            pcComponentDTO.getPcHardDisks(),
                                            pcComponentDTO.getPcPowerSupplies(),
                                            pcComponentDTO.getPcCases(),
                                            ahpPcComponentPriceWeightDTO.getBudgetPrice());
                    } else {
                        // 普通变异
                        mutate(child,   pcComponentDTO.getPcMotherboards(),
                                        pcComponentDTO.getPcCpus(),
                                        pcComponentDTO.getPcCoolers(),
                                        pcComponentDTO.getPcGpus(),
                                        pcComponentDTO.getPcMemorys(),
                                        pcComponentDTO.getPcHardDisks(),
                                        pcComponentDTO.getPcPowerSupplies(),
                                        pcComponentDTO.getPcCases());
                    }
                    newPopulation.add(child);
                    if (newPopulation.size() >= GaConfig.Easy.POPULATION_SIZE) {
                        break;
                    }
                }
            }
            // 限制种群大小
            if (newPopulation.size() > GaConfig.Easy.POPULATION_SIZE) {
                newPopulation = newPopulation.subList(0, GaConfig.Easy.POPULATION_SIZE);
            }
            // 更新种群
            populations = newPopulation;
        }

        // 评估最终种群
        List<Individual> evaluatedPopulation = evaluatePopulation(populations, ahpPcComponentPriceWeightDTO.getBudgetPrice());

        // 按适应度排序
        evaluatedPopulation.sort((a, b) -> Double.compare(b.fitness(), a.fitness()));

        // 返回指定数量的多样性最佳配置
        List<PcDTO> diverseResults = getDiverseResults(evaluatedPopulation, GaConfig.Easy.RESULT_COUNT);
        if (!diverseResults.isEmpty()) {
            return new PcVO().convertPcVOList(diverseResults);
        }
        return List.of();
    }

    /**
     * 初始化种群
     * 创建初始的随机电脑配置种群，每个配置尝试按照合理的比例分配预算在各个组件上
     *
     * @param pcComponentDTO 电脑组件DTO
     * @param populationSize 种群大小
     * @param ahpPcComponentPriceWeightDTO 价格权重DTO
     * @return 初始化后的电脑配置种群
     */
    private List<PcDTO> initializePopulation(PcComponentDTO pcComponentDTO, int populationSize, AhpPcComponentPriceWeightDTO ahpPcComponentPriceWeightDTO) {
        List<PcDTO> population = new ArrayList<>();
        Random random = new Random();
        
        for (int i = 0; i < populationSize; i++) {
            PcDTO pc = new PcDTO();
            // 在预算范围内随机选择组件
            pc.setPcMotherboard(getRandomComponentWithinBudget(pcComponentDTO.getPcMotherboards(), ahpPcComponentPriceWeightDTO.getPcMotherboard(), random));
            pc.setPcCpu(getRandomComponentWithinBudget(pcComponentDTO.getPcCpus(), ahpPcComponentPriceWeightDTO.getPcCpu(), random));
            pc.setPcGpu(getRandomComponentWithinBudget(pcComponentDTO.getPcGpus(), ahpPcComponentPriceWeightDTO.getPcGpu(), random));
            pc.setPcMemory(getRandomComponentWithinBudget(pcComponentDTO.getPcMemorys(), ahpPcComponentPriceWeightDTO.getPcMemory(), random));
            pc.setPcHardDisk(getRandomComponentWithinBudget(pcComponentDTO.getPcHardDisks(), ahpPcComponentPriceWeightDTO.getPcHardDisk(), random));
            pc.setPcPowerSupply(getRandomComponentWithinBudget(pcComponentDTO.getPcPowerSupplies(), ahpPcComponentPriceWeightDTO.getPcPowerSupply(), random));
            pc.setPcCooler(getRandomComponentWithinBudget(pcComponentDTO.getPcCoolers(), ahpPcComponentPriceWeightDTO.getPcCooler(), random));
            pc.setPcCase(getRandomComponentWithinBudget(pcComponentDTO.getPcCases(), ahpPcComponentPriceWeightDTO.getPcCase(), random));
            population.add(pc);
        }
        
        return population;
    }
    
    /**
     * 在预算范围内随机选择一个组件
     * 尝试选择价格接近预算的组件，如果没有符合条件的组件，则随机选择一个
     *
     * @param components 组件列表
     * @param budget 预算限制
     * @param random 随机数生成器
     * @param <T> 组件类型
     * @return 选中的组件
     */
    private <T extends Object> T getRandomComponentWithinBudget(List<T> components, BigDecimal budget, Random random) {
        if (components == null || components.isEmpty()) {
            return null;
        }

        // 尝试在预算范围内选择组件
        List<T> candidates = new ArrayList<>();
        for (T component : components) {
            candidates.add(component);
        }

        // 优先选择价格接近预算的组件
        candidates.sort((a, b) -> {
            BigDecimal priceA = getComponentPrice(a);
            BigDecimal priceB = getComponentPrice(b);
            BigDecimal diffA = priceA.subtract(budget).abs();
            BigDecimal diffB = priceB.subtract(budget).abs();
            return diffA.compareTo(diffB);
        });

        // 从排序后的前20%组件中随机选择一个
        int topN = Math.max(1, (int) (candidates.size() * 0.2));
        return candidates.get(random.nextInt(topN));
    }

    private static <T extends Object> BigDecimal getComponentPrice(T component) {
        // 根据组件类型获取价格
        if (component instanceof PcCpu) {
            return ((PcCpu) component).getPrice();
        } else if (component instanceof PcGpu) {
            return ((PcGpu) component).getPrice();
        } else if (component instanceof PcMotherboard) {
            return ((PcMotherboard) component).getPrice();
        } else if (component instanceof PcMemory) {
            return ((PcMemory) component).getPrice();
        } else if (component instanceof PcHardDisk) {
            return ((PcHardDisk) component).getPrice();
        } else if (component instanceof PcPowerSupply) {
            return ((PcPowerSupply) component).getPrice();
        } else if (component instanceof PcCooler) {
            return ((PcCooler) component).getPrice();
        } else if (component instanceof PcCase) {
            return ((PcCase) component).getPrice();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 评估种群适应度
     * 对种群中的每台电脑配置计算其适应度值
     * 适应度值根据价格匹配度、组件完整性和硬件兼容性综合计算
     * 价格匹配度：配置价格与目标价格的差异程度，差异越小适应度越高
     * 组件完整性：配置是否包含所有必要组件，完整性越高适应度越高
     * 硬件兼容性：配置的组件是否能正常工作，兼容性越高适应度越高
     *
     * @param population 待评估的电脑配置种群
     * @param budgetPrice 目标价格
     * @return 包含适应度信息的个体列表
     */
    private List<Individual> evaluatePopulation(List<PcDTO> population, BigDecimal budgetPrice) {
        List<Individual> evaluatedPopulation = new ArrayList<>();

        for (PcDTO pc : population) {
            // 计算个体适应度
            double fitness = calculateFitness(pc, budgetPrice);
            // 添加到评估种群中
            evaluatedPopulation.add(new Individual(pc, fitness));
        }

        return evaluatedPopulation;
    }

    /**
     * 计算个体适应度
     * 根据价格匹配度、组件完整性和硬件兼容性综合计算配置的适应度
     * 价格匹配度权重最高(0.6)，其次是兼容性(0.3)，最后是完整性(0.1)
     *
     * @param pc 电脑配置
     * @param budgetPrice 目标价格
     * @return 适应度值，范围在0-1之间，值越高表示配置越优
     */
    private double calculateFitness(PcDTO pc, BigDecimal budgetPrice) {
        // 计算价格匹配度 (0-1)
        BigDecimal totalPrice = calculateTotalPrice(pc);
        double priceFitness = calculatePriceFitness(totalPrice, budgetPrice);
        
        // 计算组件完整性 (0-1)
        double completenessFitness = calculateCompleteness(pc);
        
        // 计算硬件兼容性 (0-1)
        double compatibilityFitness = calculateCompatibility(pc);
        
        // 加权综合适应度
        double fitness = priceFitness * 0.6 + compatibilityFitness * 0.3 + completenessFitness * 0.1;
        
        return Math.max(0, Math.min(1, fitness)); // 确保在0-1范围内
    }
    
    /**
     * 计算电脑配置的总价
     */
    private BigDecimal calculateTotalPrice(PcDTO pc) {
        BigDecimal total = BigDecimal.ZERO;
        
        if (pc.getPcMotherboard() != null && pc.getPcMotherboard().getPrice() != null) {
            total = total.add(pc.getPcMotherboard().getPrice());
        }
        if (pc.getPcCpu() != null && pc.getPcCpu().getPrice() != null) {
            total = total.add(pc.getPcCpu().getPrice());
        }
        if (pc.getPcCooler() != null && pc.getPcCooler().getPrice() != null) {
            total = total.add(pc.getPcCooler().getPrice());
        }
        if (pc.getPcGpu() != null && pc.getPcGpu().getPrice() != null) {
            total = total.add(pc.getPcGpu().getPrice());
        }
        if (pc.getPcMemory() != null && pc.getPcMemory().getPrice() != null) {
            total = total.add(pc.getPcMemory().getPrice());
        }
        if (pc.getPcHardDisk() != null && pc.getPcHardDisk().getPrice() != null) {
            total = total.add(pc.getPcHardDisk().getPrice());
        }
        if (pc.getPcPowerSupply() != null && pc.getPcPowerSupply().getPrice() != null) {
            total = total.add(pc.getPcPowerSupply().getPrice());
        }
        if (pc.getPcCase() != null && pc.getPcCase().getPrice() != null) {
            total = total.add(pc.getPcCase().getPrice());
        }
        
        return total;
    }

    /**
     * 计算价格匹配度
     */
    private double calculatePriceFitness(BigDecimal totalPrice, BigDecimal budgetPrice) {
        // 使用高斯函数计算价格接近度
        double ratio = totalPrice.divide(budgetPrice, 2, RoundingMode.HALF_UP).doubleValue();
        // 价格在目标价格的80%-120%之间时适应度较高
        if (ratio == 1.0) {
            return 1.0;
        }
        // 当价格在目标价格的80%-120%范围内时，使用二次函数计算适应度
        // 价格完全匹配时适应度为1，偏离越多适应度越低
        if (ratio >= 0.8 && ratio <= 1.2) {
            return 1.0 - Math.pow(ratio - 1.0, 2) * 2.5;
        // 当价格低于目标价格的80%时，使用指数衰减函数计算适应度
        // 价格越低适应度越低，但不会完全为0
        } else if (ratio < 0.8) {
            return 0.5 * Math.exp(-Math.pow(ratio - 0.8, 2) / 0.02);
        // 当价格高于目标价格的120%时，使用指数衰减函数计算适应度
        // 价格越高适应度越低，但衰减速度比低价时慢
        } else {
            return 0.5 * Math.exp(-Math.pow(ratio - 1.2, 2) / 0.08);
        }
    }
    
    /**
     * 计算组件完整性
     */
    private double calculateCompleteness(PcDTO pc) {
        int count = 0;
        int totalComponents = 8; // 总共有8个组件
        
        if (pc.getPcMotherboard() != null) count++;
        if (pc.getPcCpu() != null) count++;
        if (pc.getPcCooler() != null) count++;
        if (pc.getPcGpu() != null) count++;
        if (pc.getPcMemory() != null) count++;
        if (pc.getPcHardDisk() != null) count++;
        if (pc.getPcPowerSupply() != null) count++;
        if (pc.getPcCase() != null) count++;
        
        return (double) count / totalComponents;
    }
    
    /**
     * 计算硬件兼容性得分
     * 实现了详细的硬件兼容性检查逻辑，包括接口匹配、功率需求、尺寸兼容等
     *
     * @param pc 电脑配置
     * @return 兼容性得分，范围在0-1之间
     */
    private double calculateCompatibility(PcDTO pc) {

        // 默认得分为1.0
        double compatibilityScore = 1.0;

        // 检查关键组件是否存在
        if (pc.getPcMotherboard() == null || pc.getPcCpu() == null || pc.getPcGpu() == null) {
            return 0.0;
        }

        // todo 配件之间兼容性检查
        
        // 确保得分在0-1范围内
        return Math.max(0.0, Math.min(1.0, compatibilityScore));
    }
    
    /**
     * 选择父代（轮盘赌选择）
     * 根据个体适应度值进行选择，适应度越高的个体被选中的概率越大
     *
     * @param evaluatedPopulation 已评估的种群
     * @return 选中的父代个体
     */
    private Individual selectParent(List<Individual> evaluatedPopulation) {
        if (evaluatedPopulation.isEmpty()) {
            return null;
        }
        
        // 计算总适应度
        double totalFitness = 0;
        for (Individual individual : evaluatedPopulation) {
            totalFitness += individual.fitness();
        }
        
        // 如果总适应度为0，随机选择一个
        if (totalFitness <= 0) {
            return evaluatedPopulation.get(new Random().nextInt(evaluatedPopulation.size()));
        }
        
        // 轮盘赌选择
        Random random = new Random();
        double randomValue = random.nextDouble() * totalFitness;
        double cumulativeFitness = 0;
        
        for (Individual individual : evaluatedPopulation) {
            cumulativeFitness += individual.fitness();
            if (cumulativeFitness >= randomValue) {
                return individual;
            }
        }
        
        // 如果出现异常情况，返回第一个个体
        return evaluatedPopulation.get(0);
    }
    
    /**
     * 交叉操作
     * 在两个父代配置之间随机交换硬件组件，生成新的配置组合
     *
     * @param parent1 第一个父代配置
     * @param parent2 第二个父代配置
     * @return 生成的两个子代配置
     */
    private List<PcDTO> crossover(PcDTO parent1, PcDTO parent2) {
        List<PcDTO> children = new ArrayList<>();
        PcDTO child1 = new PcDTO();
        PcDTO child2 = new PcDTO();
        
        Random random = new Random();
        
        // 对每个组件进行随机选择，来自父代1或父代2
        child1.setPcMotherboard(random.nextBoolean() ? parent1.getPcMotherboard() : parent2.getPcMotherboard());
        child1.setPcCpu(random.nextBoolean() ? parent1.getPcCpu() : parent2.getPcCpu());
        child1.setPcCooler(random.nextBoolean() ? parent1.getPcCooler() : parent2.getPcCooler());
        child1.setPcGpu(random.nextBoolean() ? parent1.getPcGpu() : parent2.getPcGpu());
        child1.setPcMemory(random.nextBoolean() ? parent1.getPcMemory() : parent2.getPcMemory());
        child1.setPcHardDisk(random.nextBoolean() ? parent1.getPcHardDisk() : parent2.getPcHardDisk());
        child1.setPcPowerSupply(random.nextBoolean() ? parent1.getPcPowerSupply() : parent2.getPcPowerSupply());
        child1.setPcCase(random.nextBoolean() ? parent1.getPcCase() : parent2.getPcCase());
        
        // 第二个子代可以简单地使用相反的选择，或者也进行随机选择
        child2.setPcMotherboard(random.nextBoolean() ? parent1.getPcMotherboard() : parent2.getPcMotherboard());
        child2.setPcCpu(random.nextBoolean() ? parent1.getPcCpu() : parent2.getPcCpu());
        child2.setPcCooler(random.nextBoolean() ? parent1.getPcCooler() : parent2.getPcCooler());
        child2.setPcGpu(random.nextBoolean() ? parent1.getPcGpu() : parent2.getPcGpu());
        child2.setPcMemory(random.nextBoolean() ? parent1.getPcMemory() : parent2.getPcMemory());
        child2.setPcHardDisk(random.nextBoolean() ? parent1.getPcHardDisk() : parent2.getPcHardDisk());
        child2.setPcPowerSupply(random.nextBoolean() ? parent1.getPcPowerSupply() : parent2.getPcPowerSupply());
        child2.setPcCase(random.nextBoolean() ? parent1.getPcCase() : parent2.getPcCase());
        
        children.add(child1);
        children.add(child2);
        
        return children;
    }
    
    /**
     * 变异操作
     * 随机选择一个硬件组件，并用同类型的其他可用组件替换它
     * 增加种群多样性，避免算法过早收敛
     *
     * @param pc 待变异的电脑配置
     * @param motherboards 可选的主板列表
     * @param cpus 可选的CPU列表
     * @param coolers 可选的散热器列表
     * @param gpus 可选的显卡列表
     * @param memories 可选的内存列表
     * @param hardDisks 可选的硬盘列表
     * @param powerSupplies 可选的电源列表
     * @param cases 可选的机箱列表
     */
    private void mutate(
            PcDTO pc, List<PcMotherboard> motherboards, List<PcCpu> cpus, List<PcCooler> coolers,
            List<PcGpu> gpus, List<PcMemory> memories, List<PcHardDisk> hardDisks,
            List<PcPowerSupply> powerSupplies, List<PcCase> cases) {
        Random random = new Random();
        int componentType = random.nextInt(8); // 随机选择要变异的组件类型
        
        // 根据随机选择的组件类型执行变异
        switch (componentType) {
            case 0: // 主板
                if (!motherboards.isEmpty()) {
                    pc.setPcMotherboard(motherboards.get(random.nextInt(motherboards.size())));
                }
                break;
            case 1: // CPU
                if (!cpus.isEmpty()) {
                    pc.setPcCpu(cpus.get(random.nextInt(cpus.size())));
                }
                break;
            case 2: // 散热器
                if (!coolers.isEmpty()) {
                    pc.setPcCooler(coolers.get(random.nextInt(coolers.size())));
                }
                break;
            case 3: // 显卡
                if (!gpus.isEmpty()) {
                    pc.setPcGpu(gpus.get(random.nextInt(gpus.size())));
                }
                break;
            case 4: // 内存
                if (!memories.isEmpty()) {
                    pc.setPcMemory(memories.get(random.nextInt(memories.size())));
                }
                break;
            case 5: // 硬盘
                if (!hardDisks.isEmpty()) {
                    pc.setPcHardDisk(hardDisks.get(random.nextInt(hardDisks.size())));
                }
                break;
            case 6: // 电源
                if (!powerSupplies.isEmpty()) {
                    pc.setPcPowerSupply(powerSupplies.get(random.nextInt(powerSupplies.size())));
                }
                break;
            case 7: // 机箱
                if (!cases.isEmpty()) {
                    pc.setPcCase(cases.get(random.nextInt(cases.size())));
                }
                break;
        }
    }
    
    /**
     * 智能变异操作
     * 根据当前配置的适应度分析，优先变异那些对整体性能影响较大或兼容性较差的组件
     * 提高了变异的针对性，加快算法收敛速度
     *
     * @param pc 待变异的电脑配置
     * @param motherboards 可选的主板列表
     * @param cpus 可选的CPU列表
     * @param coolers 可选的散热器列表
     * @param gpus 可选的显卡列表
     * @param memories 可选的内存列表
     * @param hardDisks 可选的硬盘列表
     * @param powerSupplies 可选的电源列表
     * @param cases 可选的机箱列表
     * @param budgetPrice 目标价格
     */
    private void smartMutate(
            PcDTO pc, List<PcMotherboard> motherboards, List<PcCpu> cpus, List<PcCooler> coolers,
            List<PcGpu> gpus, List<PcMemory> memories, List<PcHardDisk> hardDisks,
            List<PcPowerSupply> powerSupplies, List<PcCase> cases, BigDecimal budgetPrice) {
        
        // 评估当前配置的各组件对总适应度的贡献
        // 计算各组件的预算匹配度
        Map<String, Double> componentBudgetScores = new HashMap<>();
        
        // 计算各组件的预算
        BigDecimal cpuBudget = budgetPrice.multiply(BigDecimal.valueOf(0.3));
        BigDecimal gpuBudget = budgetPrice.multiply(BigDecimal.valueOf(0.3));
        BigDecimal motherboardBudget = budgetPrice.multiply(BigDecimal.valueOf(0.1));
        BigDecimal memoryBudget = budgetPrice.multiply(BigDecimal.valueOf(0.1));
        BigDecimal hardDiskBudget = budgetPrice.multiply(BigDecimal.valueOf(0.08));
        BigDecimal powerSupplyBudget = budgetPrice.multiply(BigDecimal.valueOf(0.07));
        BigDecimal coolerBudget = budgetPrice.multiply(BigDecimal.valueOf(0.03));
        BigDecimal caseBudget = budgetPrice.multiply(BigDecimal.valueOf(0.02));
        
        // 计算各组件的预算匹配度
        if (pc.getPcCpu() != null) {
            componentBudgetScores.put("cpu", calculateComponentBudgetScore(pc.getPcCpu().getPrice(), cpuBudget));
        }
        if (pc.getPcGpu() != null) {
            componentBudgetScores.put("gpu", calculateComponentBudgetScore(pc.getPcGpu().getPrice(), gpuBudget));
        }
        if (pc.getPcMotherboard() != null) {
            componentBudgetScores.put("motherboard", calculateComponentBudgetScore(pc.getPcMotherboard().getPrice(), motherboardBudget));
        }
        if (pc.getPcMemory() != null) {
            componentBudgetScores.put("memory", calculateComponentBudgetScore(pc.getPcMemory().getPrice(), memoryBudget));
        }
        if (pc.getPcHardDisk() != null) {
            componentBudgetScores.put("hardDisk", calculateComponentBudgetScore(pc.getPcHardDisk().getPrice(), hardDiskBudget));
        }
        if (pc.getPcPowerSupply() != null) {
            componentBudgetScores.put("powerSupply", calculateComponentBudgetScore(pc.getPcPowerSupply().getPrice(), powerSupplyBudget));
        }
        if (pc.getPcCooler() != null) {
            componentBudgetScores.put("cooler", calculateComponentBudgetScore(pc.getPcCooler().getPrice(), coolerBudget));
        }
        if (pc.getPcCase() != null) {
            componentBudgetScores.put("case", calculateComponentBudgetScore(pc.getPcCase().getPrice(), caseBudget));
        }
        
        // 找出得分最低的几个组件
        List<String> worstComponents = componentBudgetScores.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())
                .limit(3) // 选择得分最低的3个组件
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        
        // 额外检查兼容性问题
        double compatibilityScore = calculateCompatibility(pc);
        if (compatibilityScore < 0.7) {
            // 兼容性较差，需要重点优化
            // 检查关键兼容性问题
            if (pc.getPcMotherboard() != null && pc.getPcCpu() != null && 
                pc.getPcMotherboard().getCpuSupport() != null && pc.getPcCpu().getSocketType() != null &&
                !pc.getPcMotherboard().getCpuSupport().equals(pc.getPcCpu().getSocketType())) {
                // CPU和主板接口不兼容，优先变异这两个组件
                worstComponents.add("motherboard");
                worstComponents.add("cpu");
            }
        }
        
        // 从最差组件中随机选择一个进行变异
        if (!worstComponents.isEmpty()) {
            Random random = new Random();
            String componentToMutate = worstComponents.get(random.nextInt(worstComponents.size()));
            
            // 执行针对性变异
            switch (componentToMutate) {
                case "cpu":
                     if (!cpus.isEmpty()) {
                         // 选择与当前主板兼容的CPU
                         List<PcCpu> compatibleCpus = new ArrayList<>();
                         if (pc.getPcMotherboard() != null && pc.getPcMotherboard().getCpuSupport() != null) {
                             for (PcCpu cpu : cpus) {
                                 if (cpu.getSocketType() != null && cpu.getSocketType().equals(pc.getPcMotherboard().getCpuSupport())) {
                                     compatibleCpus.add(cpu);
                                 }
                             }
                         }
                         
                         if (!compatibleCpus.isEmpty()) {
                             pc.setPcCpu((PcCpu) getRandomComponentWithinBudget(compatibleCpus, cpuBudget, random));
                         } else {
                             pc.setPcCpu(cpus.get(random.nextInt(cpus.size())));
                         }
                     }
                     break;
                case "gpu":
                    if (!gpus.isEmpty()) {
                        pc.setPcGpu((PcGpu) getRandomComponentWithinBudget(gpus, gpuBudget, random));
                    }
                    break;
                case "motherboard":
                     if (!motherboards.isEmpty()) {
                         // 选择与当前CPU兼容的主板
                         List<PcMotherboard> compatibleMotherboards = new ArrayList<>();
                         if (pc.getPcCpu() != null && pc.getPcCpu().getSocketType() != null) {
                             for (PcMotherboard motherboard : motherboards) {
                                 if (motherboard.getCpuSupport() != null && motherboard.getCpuSupport().equals(pc.getPcCpu().getSocketType())) {
                                     compatibleMotherboards.add(motherboard);
                                 }
                             }
                         }
                         
                         if (!compatibleMotherboards.isEmpty()) {
                             pc.setPcMotherboard((PcMotherboard) getRandomComponentWithinBudget(compatibleMotherboards, motherboardBudget, random));
                         } else {
                             pc.setPcMotherboard(motherboards.get(random.nextInt(motherboards.size())));
                         }
                     }
                     break;
                case "memory":
                     if (!memories.isEmpty()) {
                         pc.setPcMemory((PcMemory) getRandomComponentWithinBudget(memories, memoryBudget, random));
                     }
                     break;
                case "powerSupply":
                     if (!powerSupplies.isEmpty()) {
                         // 优先选择功率足够的电源
                         int estimatedPower = estimateSystemPower(pc);
                         List<PcPowerSupply> sufficientPowerSupplies = new ArrayList<>();
//                         for (PcPowerSupply psu : powerSupplies) {
//                             if (psu.getWattage() != null && psu.getWattage() >= estimatedPower * 1.2) {
//                                 sufficientPowerSupplies.add(psu);
//                             }
//                         }
                         
                         if (!sufficientPowerSupplies.isEmpty()) {
                             pc.setPcPowerSupply((PcPowerSupply) getRandomComponentWithinBudget(sufficientPowerSupplies, powerSupplyBudget, random));
                         } else {
                             pc.setPcPowerSupply(powerSupplies.get(random.nextInt(powerSupplies.size())));
                         }
                     }
                     break;
                case "hardDisk":
                    if (!hardDisks.isEmpty()) {
                        pc.setPcHardDisk((PcHardDisk) getRandomComponentWithinBudget(hardDisks, hardDiskBudget, random));
                    }
                    break;
                case "cooler":
                     if (!coolers.isEmpty()) {
                         // 选择与当前CPU兼容的散热器
                         List<PcCooler> compatibleCoolers = new ArrayList<>();
                         if (pc.getPcCpu() != null && pc.getPcCpu().getSocketType() != null) {
//                             for (PcCooler cooler : coolers) {
//                                 if (cooler.getSocket() != null && cooler.getSocket().equals(pc.getPcCpu().getSocketType())) {
//                                     compatibleCoolers.add(cooler);
//                                 }
//                             }
                         }
                         
                         if (!compatibleCoolers.isEmpty()) {
                             pc.setPcCooler((PcCooler) getRandomComponentWithinBudget(compatibleCoolers, coolerBudget, random));
                         } else {
                             pc.setPcCooler(coolers.get(random.nextInt(coolers.size())));
                         }
                     }
                     break;
                case "case":
                     if (!cases.isEmpty()) {
                         // 选择能够容纳当前散热器的机箱
                         List<PcCase> compatibleCases = new ArrayList<>();
                         for (PcCase pcCase : cases) {
                             boolean compatible = true;
                             
                             // 检查散热器高度
//                             if (pc.getPcCooler() != null && pc.getPcCooler().getHeight() != null &&
//                                 pcCase.getMaxCoolerHeight() != null &&
//                                 pc.getPcCooler().getHeight() > pcCase.getMaxCoolerHeight()) {
//                                 compatible = false;
//                             }
                             
                             if (compatible) {
                                 compatibleCases.add(pcCase);
                             }
                         }
                         
                         if (!compatibleCases.isEmpty()) {
                             pc.setPcCase((PcCase) getRandomComponentWithinBudget(compatibleCases, caseBudget, random));
                         } else {
                             pc.setPcCase(cases.get(random.nextInt(cases.size())));
                         }
                     }
                     break;
            }
        }
    }
    
    /**
     * 估算系统总功率需求
     * 
     * @param pc 电脑配置
     * @return 估算的功率需求（W）
     */
    private int estimateSystemPower(PcDTO pc) {
        int power = 100; // 基础功率需求
        
        if (pc.getPcCpu() != null && pc.getPcCpu().getMaxTurboPwr() != null) {
            power += pc.getPcCpu().getMaxTurboPwr();
        }
        
        if (pc.getPcGpu() != null && pc.getPcGpu().getTdp() != null) {
            power += pc.getPcGpu().getTdp();
        }
        
        // 考虑超频等因素，增加20%的余量
        return (int) (power * 1.2);
    }
    
    /**
     * 计算组件预算匹配得分
     * 
     * @param actualPrice 组件实际价格
     * @param budget 组件预算
     * @return 匹配得分，范围在0-1之间
     */
    private double calculateComponentBudgetScore(BigDecimal actualPrice, BigDecimal budget) {
        if (budget.compareTo(BigDecimal.ZERO) <= 0) {
            return 1.0;
        }
        
        double ratio = actualPrice.divide(budget, 2, RoundingMode.HALF_UP).doubleValue();
        if (ratio >= 0.8 && ratio <= 1.2) {
            return 1.0 - Math.pow(ratio - 1.0, 2) * 2.5;
        } else if (ratio < 0.8) {
            return 0.5 * Math.exp(-Math.pow(ratio - 0.8, 2) / 0.02);
        } else {
            return 0.5 * Math.exp(-Math.pow(ratio - 1.2, 2) / 0.08);
        }
    }
    
    /**
     * 计算种群多样性
     * 通过计算种群中不同配置的比例来评估多样性
     * 
     * @param evaluatedPopulation 已评估的种群
     * @return 多样性得分，范围在0-1之间
     */
    private double calculatePopulationDiversity(List<Individual> evaluatedPopulation) {
        if (evaluatedPopulation.isEmpty()) {
            return 0.0;
        }
        
        // 使用配置哈希来识别不同的配置
        Set<String> uniqueConfigs = new HashSet<>();
        for (Individual individual : evaluatedPopulation) {
            uniqueConfigs.add(generateConfigHash(individual.pc()));
        }
        
        // 计算多样性得分：唯一配置数量除以总配置数量
        return (double) uniqueConfigs.size() / evaluatedPopulation.size();
    }
    
    /**
     * 锦标赛选择父代
     * 从种群中随机选择一定数量的个体，然后选择其中适应度最高的个体作为父代
     * 结合了随机性和精英选择的优点
     * 
     * @param evaluatedPopulation 已评估的种群
     * @param tournamentSize 锦标赛大小
     * @return 选中的父代个体
     */
    private Individual selectParentTournament(List<Individual> evaluatedPopulation, int tournamentSize) {
        if (evaluatedPopulation.isEmpty()) {
            return null;
        }
        
        Random random = new Random();
        Individual best = null;
        
        // 随机选择tournamentSize个个体进行比赛
        for (int i = 0; i < tournamentSize; i++) {
            int randomIndex = random.nextInt(evaluatedPopulation.size());
            Individual candidate = evaluatedPopulation.get(randomIndex);
            
            if (best == null || candidate.fitness() > best.fitness()) {
                best = candidate;
            }
        }
        
        return best;
    }
    
    /**
     * 获取多样性的结果
     * 从评估后的种群中选择指定数量的配置，确保结果具有足够的多样性
     * 通过配置哈希值来判断配置的唯一性
     *
     * @param evaluatedPopulation 已评估的种群
     * @param count 需要返回的结果数量
     * @return 具有多样性的最佳配置列表
     */
    private List<PcDTO> getDiverseResults(List<Individual> evaluatedPopulation, int count) {
        List<PcDTO> results = new ArrayList<>();
        Set<String> seenConfigs = new HashSet<>();
        
        for (Individual individual : evaluatedPopulation) {
            PcDTO pc = individual.pc();
            
            // 生成配置的唯一标识符（简单的哈希方法）
            String configHash = generateConfigHash(pc);
            
            if (!seenConfigs.contains(configHash)) {
                results.add(pc);
                seenConfigs.add(configHash);
                
                if (results.size() >= count) {
                    break;
                }
            }
        }
        
        // 如果没有足够的多样性，补充其他配置
        if (results.size() < count) {
            for (Individual individual : evaluatedPopulation) {
                if (!results.contains(individual.pc())) {
                    results.add(individual.pc());
                    
                    if (results.size() >= count) {
                        break;
                    }
                }
            }
        }
        
        return results;
    }
    
    /**
     * 生成配置的哈希值，用于检查多样性
     * 使用关键组件(主板、CPU、显卡)的型号生成唯一标识符
     *
     * @param pc 电脑配置
     * @return 配置的哈希字符串
     */
    private String generateConfigHash(PcDTO pc) {
        StringBuilder sb = new StringBuilder();
        
        if (pc.getPcMotherboard() != null) sb.append(pc.getPcMotherboard().getModel()).append("|");
        if (pc.getPcCpu() != null) sb.append(pc.getPcCpu().getModel()).append("|");
        if (pc.getPcGpu() != null) sb.append(pc.getPcGpu().getModel()).append("|");
        
        return sb.toString();
    }
    
    /**
     * 校验输入参数是否符合要求
     * @param dto 电脑配件价格权重DTO
     */
    private void validateInputParameters(AhpPcComponentPriceWeightDTO dto) {
        // 校验价格是否为正
        if (dto.getBudgetPrice() == null || dto.getBudgetPrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("价格必须为正");
        }
    }
}